using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using AForge.Imaging.Filters;
using System.Drawing.Imaging;

namespace PBR
{
    class VectorImage
    {
        private const int NUMNEIGHBORS = 5;

        public BitmapUnsafe Apply(KDTreeDLL.KDTree angles, int width, int height)
        {
            return Apply(angles, width, height, 1);
        }

        public BitmapUnsafe Apply(KDTreeDLL.KDTree angles, int width, int height, int distance)
        {
            //To Do - add the color pallete stuff\
            BitmapUnsafe vectorImage = new BitmapUnsafe(XMLSchema.VectorImage, width, height, PixelFormat.Format8bppIndexed);
            int numNeighbors = NUMNEIGHBORS;

            if (angles.Count == 0)
            {
                return vectorImage;
            }
            else if (angles.Count < numNeighbors)
            {
                numNeighbors = angles.Count;
            }

            vectorImage.Lock(ImageLockMode.WriteOnly);

            double[] dLoc = new double[2] { 0.0, 0.0 };
            Object[] nodeList;
            byte currValue;
            double power = 3.0;

			// for each line
			for ( int y = 0; y < height; y += distance)
			{
				// for each pixel
				for ( int x = 0; x < width; x += distance)
				{
                    dLoc[0] = x;
                    dLoc[1] = y;
                    nodeList = angles.Nearest(dLoc, numNeighbors);

                    currValue = 0;
                    double numerator = 0;
                    double denominator = 0;
                    foreach (KDNodeData node in nodeList)
                    {
                        double weight = 1.0 / (Math.Pow(Distance(node.point, x, y), power));
                        numerator += weight * node.angle;
                        denominator += weight;
                    }

                    byte value = (byte)(numerator / denominator);
                    if ( value > 255 )
                    {
                        value = 255;
                    }

                    vectorImage.SetCellBW(value, x, y);
			    }
			}

            vectorImage.Unlock();

            return vectorImage;
        }

        private double Distance(Point point, int x, int y)
        {
            return Math.Sqrt((point.X - x) * (point.X - x) + (point.Y - y) * (point.Y - y));
        }
    }
}
